// src-tauri/src/trust_network_client.rs
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, num::NonZero, time::Duration};
use libp2p::futures::StreamExt;
// src-tauri/src/trust_network_client.rs
use libp2p::{
    kad::{self, QueryResult, Record, RecordKey},
    noise,
    swarm::{Swarm, SwarmEvent},
    tcp,
    yamux,
    Multiaddr, PeerId, identity::Keypair,
};
use libp2p::Transport;
// 导入其他必要的类型
// 暂时注释掉PeerStore导入，先解决编译问题
// use crate::reputation_system::PeerStore;
use tokio::sync::mpsc;

#[derive(Serialize, Deserialize, Clone)]
pub struct DhtRecord {
    pub key: String,
    pub value: Vec<u8>,
    pub publisher: Option<String>,
    pub expires: Option<u64>,
}

pub struct DhtClient {
    swarm: Swarm<kad::Behaviour<libp2p::kad::store::MemoryStore>>,
    pending_queries: HashMap<libp2p::kad::QueryId, PendingQuery>,
    event_sender: mpsc::UnboundedSender<DhtEvent>,
    local_peer_id: PeerId,
}

#[derive(Debug)]
pub enum DhtEvent {
    RecordFound {
        key: RecordKey,
        record: Record,
        peer: PeerId,
    },
    RecordStored {
        key: RecordKey,
        peers: Vec<PeerId>,
    },
    PeerDiscovered(PeerId),
    BootstrapCompleted,
    Error(String),
}

struct PendingQuery {
    query_type: QueryType,
    start_time: std::time::Instant,
}

enum QueryType {
    GetRecord,
    PutRecord,
    GetClosestPeers,
}

impl DhtClient {
    pub fn new(local_key: Keypair) -> (Self, mpsc::UnboundedReceiver<DhtEvent>) {
        let local_peer_id = PeerId::from(local_key.public());
        
        // 创建传输层
        let transport = 
        tcp::Transport::new(tcp::Config::default())
            .upgrade(libp2p::core::upgrade::Version::V1)
            .authenticate(noise::Config::new(&local_key).expect("Noise config error"))
            .multiplex(yamux::Config::default())
            .boxed();

        // 创建Kademlia DHT配置
    let kademlia_config = kad::Config::default();
        kademlia_config.set_replication_factor(NonZero::new(20).unwrap()); // K值
        kademlia_config.set_query_timeout(std::time::Duration::from_secs(30));

        let kademlia = kad::Behaviour::<libp2p::kad::store::MemoryStore>::new(local_peer_id, kademlia_config);

        let swarm = libp2p::Swarm::new(
            transport,
            kademlia,
            local_peer_id,
            libp2p::swarm::Config::without_executor(),
        );

        let (event_sender, event_receiver) = mpsc::unbounded_channel();

        let client = Self {
            swarm,
            pending_queries: HashMap::new(),
            event_sender,
            local_peer_id,
        };

        (client, event_receiver)
    }

    /// 启动DHT客户端并连接到引导节点
    pub async fn start(&mut self, bootstrap_nodes: Vec<(PeerId, Multiaddr)>) {
        // 添加引导节点到路由表
        for (peer_id, addr) in bootstrap_nodes {
            self.swarm.behaviour_mut().add_address(&peer_id, addr);
        }

        // 启动引导过程
        self.swarm.behaviour_mut().bootstrap().unwrap();
        
        println!("DHT client started with peer ID: {}", self.local_peer_id);
    }

    /// 在DHT中存储证书记录
    pub fn put_certificate(&mut self, peer_id: String, certificate_data: Vec<u8>) -> Result<(), String> {
        let record_key = RecordKey::new(&peer_id);
        let record = Record {
            key: record_key.clone(),
            value: certificate_data,
            publisher: Some(self.local_peer_id),
            expires: Some(std::time::Instant::now() + std::time::Duration::from_secs(7 * 24 * 60 * 60)), // 7天过期，使用Instant类型
        };

        // 开始存储记录
        let query_id = self.swarm.behaviour_mut().put_record(record, libp2p::kad::Quorum::One);
        match query_id {
            Ok(query_id) => {
                self.pending_queries.insert(query_id, PendingQuery {
                    query_type: QueryType::PutRecord,
                    start_time: std::time::Instant::now(),
                });
            }
            Err(e) => {
                return Err(format!("Failed to put record: {:?}", e));
            }
        }
        

        Ok(())
    }

    /// 从DHT中获取证书记录
    pub fn get_certificate(&mut self, peer_id: String) -> Result<(), String> {
        let record_key = RecordKey::new(&peer_id);
        
        // 开始查找记录
        let query_id = self.swarm.behaviour_mut().get_record(record_key);
        
        self.pending_queries.insert(query_id, PendingQuery {
            query_type: QueryType::GetRecord,
            start_time: std::time::Instant::now(),
        });

        Ok(())
    }

    /// 批量获取证书记录
    pub fn batch_get_certificates(&mut self, peer_ids: Vec<String>) -> HashMap<String, Result<DhtRecord, String>> {
        let mut results = HashMap::new();
        
        for peer_id in peer_ids {
            if let Err(e) = self.get_certificate(peer_id.clone()) {
                results.insert(peer_id, Err(e));
            }
        }
        
        results
    }

    /// 查找最近的节点
    pub fn find_closest_peers(&mut self, key: Vec<u8>) -> Result<(), String> {
        let query_id = self.swarm.behaviour_mut().get_closest_peers(key);
        
        self.pending_queries.insert(query_id, PendingQuery {
            query_type: QueryType::GetClosestPeers,
            start_time: std::time::Instant::now(),
        });

        Ok(())
    }

    /// 处理DHT事件的主循环
    pub async fn run(mut self) -> Result<(), Box<dyn std::error::Error>> {
        loop {
            tokio::select! {
                event = self.swarm.poll_next_unpin() => {
                    self.handle_swarm_event(event).await;
                }
            }
        }
    }

    /// 处理libp2p Swarm事件
    async fn handle_swarm_event(&mut self, event: SwarmEvent<kad::Event>) {
        match event {
            SwarmEvent::Behaviour(kad::Event::OutboundQueryProgressed { id, result, .. }) => {
                self.handle_query_result(id, result).await;
            }
            SwarmEvent::NewListenAddr { address, .. } => {
                println!("Listening on: {}", address);
            }
            SwarmEvent::Behaviour(kad::Event::RoutingUpdated { peer, .. }) => {
                let _ = self.event_sender.send(DhtEvent::PeerDiscovered(peer));
            }
            SwarmEvent::Behaviour(kad::Event::RoutablePeer { peer, .. }) => {
                let _ = self.event_sender.send(DhtEvent::PeerDiscovered(peer));
            }
            SwarmEvent::Behaviour(kad::Event::PendingRoutablePeer { peer, .. }) => {
                let _ = self.event_sender.send(DhtEvent::PeerDiscovered(peer));
            }
            _ => {}
        }
    }

    /// 处理查询结果
    async fn handle_query_result(&mut self, query_id: libp2p::kad::QueryId, result: QueryResult) {
        // 从待处理查询中移除
        let pending_query = self.pending_queries.remove(&query_id);
        
        if pending_query.is_none() {
            return;
        }

        match result {
            QueryResult::GetRecord(Ok(libp2p::kad::GetRecordOk::FoundRecord(record))) => {
                let record_clone = record.record.clone();
               
                
                if let Some(peer) = record.peer{
                    let _ = self.event_sender.send(DhtEvent::RecordFound {
                        key: record_clone.key.clone(),
                        record: record_clone,
                        peer: peer, 
                    });
                }
            }
            QueryResult::GetRecord(Ok(libp2p::kad::GetRecordOk::FinishedWithNoAdditionalRecord { .. })) => {
                // 没有找到记录
                let _ = self.event_sender.send(DhtEvent::Error("Record not found".to_string()));
            }
            QueryResult::GetRecord(Err(e)) => {
                let _ = self.event_sender.send(DhtEvent::Error(format!("Get record error: {:?}", e)));
            }
            QueryResult::PutRecord(Ok(libp2p::kad::PutRecordOk { key})) => {
                // let _ = self.event_sender.send(DhtEvent::RecordStored { key, peers });
            }
            QueryResult::PutRecord(Err(e)) => {
                let _ = self.event_sender.send(DhtEvent::Error(format!("Put record error: {:?}", e)));
            }
            QueryResult::GetClosestPeers(Ok(libp2p::kad::GetClosestPeersOk { key,peers: closest_peers })) => {
                for peer in closest_peers {
                    let _ = self.event_sender.send(DhtEvent::PeerDiscovered(peer.peer_id));
                }
            }
            QueryResult::GetClosestPeers(Err(e)) => {
                let _ = self.event_sender.send(DhtEvent::Error(format!("Get closest peers error: {:?}", e)));
            }
            QueryResult::Bootstrap(Ok(_)) => {
                let _ = self.event_sender.send(DhtEvent::BootstrapCompleted);
            }
            QueryResult::Bootstrap(Err(e)) => {
                let _ = self.event_sender.send(DhtEvent::Error(format!("Bootstrap error: {:?}", e)));
            }
            _ => {}
        }
    }

    /// 获取本地Peer ID
    pub fn get_local_peer_id(&self) -> PeerId {
        self.local_peer_id
    }

    /// 添加节点到路由表
    pub fn add_peer(&mut self, peer_id: PeerId, address: Multiaddr) {
        self.swarm.behaviour_mut().add_address(&peer_id, address);
    }

    /// 获取已知节点数量
    pub fn get_known_peers_count(&mut self) -> usize {
        // 注意：libp2p Kademlia 没有直接的方法获取节点数量
        // 这只是一个估计值
        self.swarm.behaviour_mut().kbuckets().count()
    }
}

/// 信任网络的引导节点配置
pub fn get_trust_network_bootstrap_nodes() -> Vec<(PeerId, Multiaddr)> {
    vec![
        // 这里添加信任网络的引导节点
        // 格式: (PeerId, Multiaddr)
        // 例如:
        // (
        //     "QmPeerIdExample...".parse().unwrap(),
        //     "/ip4/1.2.3.4/tcp/4001".parse().unwrap()
        // ),
    ]
}

/// 简化的DHT客户端包装器，用于信任网络
pub struct TrustNetworkDhtClient {
    dht_client: DhtClient,
    event_receiver: mpsc::UnboundedReceiver<DhtEvent>,
}

impl TrustNetworkDhtClient {
    pub fn new() -> Self {
        let local_key = Keypair::generate_ed25519();
        let (dht_client, event_receiver) = DhtClient::new(local_key);
        
        Self {
            dht_client,
            event_receiver,
        }
    }

    /// 启动信任网络DHT客户端
    pub async fn start(&mut self) -> Result<(), String> {
        let bootstrap_nodes = get_trust_network_bootstrap_nodes();
        self.dht_client.start(bootstrap_nodes).await;
        Ok(())
    }

    /// 发布证书到DHT
    pub fn publish_certificate(&mut self, peer_id: String, certificate_data: Vec<u8>) -> Result<(), String> {
        self.dht_client.put_certificate(peer_id, certificate_data)
    }

    /// 从DHT获取证书
    pub fn get_certificate(&mut self, peer_id: String) -> Result<(), String> {
        self.dht_client.get_certificate(peer_id)
    }

    /// 处理DHT事件
    pub async fn poll_event(&mut self) -> Option<DhtEvent> {
        self.event_receiver.recv().await
    }

    /// 运行DHT客户端（在单独的tokio任务中）
    pub fn run_in_background(mut self) -> tokio::task::JoinHandle<()> {
        tokio::spawn(async move {
            if let Err(e) = self.dht_client.run().await {
                eprintln!("DHT client error: {}", e);
            }
        })
    }
}


use crate::trust_tree::TrustCertificate;

pub struct TrustNetworkClient {
    dht_client: TrustNetworkDhtClient,
    certificate_cache: std::collections::HashMap<String, TrustCertificate>,
}

impl TrustNetworkClient {
    pub fn new() -> Self {
        Self {
            dht_client: TrustNetworkDhtClient::new(),
            certificate_cache: HashMap::new(),
        }
    }

    pub async fn start(&mut self) -> Result<(), String> {
        self.dht_client.start().await?;
        
        // 在后台运行DHT客户端
        let dht_client = std::mem::replace(&mut self.dht_client, TrustNetworkDhtClient::new());
        dht_client.run_in_background();
        
        Ok(())
    }

    /// 从DHT网络获取证书
    pub async fn get_certificate(&mut self, peer_id: &str) -> Result<TrustCertificate, String> {
        // 首先检查缓存
        if let Some(cert) = self.certificate_cache.get(peer_id) {
            return Ok(cert.clone());
        }

        // 从DHT获取
        self.dht_client.get_certificate(peer_id.to_string())?;
        
        // 等待DHT响应（简化实现）
        // 在实际系统中，这里应该等待特定的事件
        tokio::time::sleep(std::time::Duration::from_secs(2)).await;
        
        // 返回错误，表示证书未找到
        Err("Certificate not found in DHT".to_string())
    }

    /// 批量获取证书
    pub async fn batch_get_certificates(
        &mut self,
        peer_ids: &[String],
    ) -> HashMap<String, Result<TrustCertificate, String>> {
        let mut results = HashMap::new();
        
        for peer_id in peer_ids {
            match self.get_certificate(peer_id).await {
                Ok(cert) => {
                    results.insert(peer_id.clone(), Ok(cert));
                }
                Err(e) => {
                    results.insert(peer_id.clone(), Err(e));
                }
            }
        }
        
        results
    }

    /// 发布证书到DHT网络
    pub async fn publish_certificate(
        &mut self,
        certificate: &TrustCertificate,
    ) -> Result<(), String> {
        let peer_id = certificate.peer_id.clone();
        let certificate_data = serde_json::to_vec(certificate)
            .map_err(|e| format!("Failed to serialize certificate: {}", e))?;
        
        self.dht_client.publish_certificate(peer_id, certificate_data)
    }
}

